package com.lvy.hczn.transmit.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.lvy.hczn.front.common.constant.Constants;
import com.lvy.hczn.front.common.constant.MqConstants;
import com.lvy.hczn.front.common.core.domain.entity.SysDictData;
import com.lvy.hczn.front.common.exception.UtilException;
import com.lvy.hczn.front.common.utils.DictUtils;
import com.lvy.hczn.front.system.domain.business.*;
import com.lvy.hczn.front.system.domain.business.dto.ParcelDataDto;
import com.lvy.hczn.front.system.service.WarehouseService;
import com.lvy.hczn.mq.rocket.ParamInfo;
import com.lvy.hczn.mq.rocket.ProducerUtil;
import com.lvy.hczn.front.system.domain.business.dto.ParcelDetailDto;
import com.lvy.hczn.front.system.domain.business.dto.ParcelDto;
import com.lvy.hczn.transmit.domain.TemperAreaConfig;
import com.lvy.hczn.transmit.service.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;

@Service
@Slf4j
public class TParcelServiceImpl implements TParcelService {

    @Autowired
    private ProducerUtil producerUtil;

    @Autowired
    private WarehouseService warehouseService;

    @Autowired
    private TAccessManagerService tAccessManagerService;

    @Autowired
    private TDeliveryOrderInfoService tDeliveryOrderInfoService;

    @Autowired
    private GoodsBoxService goodsBoxService;
    @Autowired
    private TemperAreaConfigService temperAreaConfigService;


    @Override
    public void syncParcelPlatform(HttpServletRequest request, ParcelDto parcelDto) {
        log.error("syncParcelPlatform:{}", JSON.toJSONString(parcelDto));
//        if (paramInfo == null) {
//            throw new UtilException("数据为空");
//        }
//        ParcelDto parcelDto = paramInfo.getData();
        if (StrUtil.hasEmpty(parcelDto.getParcelNo(), parcelDto.getReceiveRep())) {
            throw new UtilException("包裹单号或揽件仓库为空");
        }
        if (CollUtil.isEmpty(parcelDto.getList())) {
            throw new UtilException("货物信息列表为空");
        }

        String bgPrefix = DictUtils.getDictValue(Constants.SYS_DICT_ORDER_TYPE, Constants.SYS_DICT_ORDER_TYPE_BG);

        var dto = parcelDto.getList().get(0);

        var id = StrUtil.removePrefix(parcelDto.getParcelNo(), bgPrefix);
        String prefix = "";
        List<SysDictData> sysDictDataList = DictUtils.getDictCache(Constants.PLATFORM_DOMAIN);
        if (sysDictDataList != null) {
            for (SysDictData dictData : sysDictDataList) {
                if (dictData.getDictLabel().equals(Constants.PLATFORM_DOMAIN_IMG)) {
                    prefix = dictData.getDictValue();
                    break;
                }
            }
        }
        // 生成SKU 和 包裹货物信息列表
        Parcel parcel = new Parcel();
        parcel.setId(parcelDto.getParcelNo());
        parcel.setParcelNo(parcelDto.getParcelNo());
        parcel.setReceiveRep(parcelDto.getReceiveRep());
        parcel.setParcelType(parcelDto.getParcelType());
        parcel.setImgUrl(prefix + parcelDto.getImgUrl());
        parcel.setTemperId(dto.getTemperId());
        parcel.setCartonCode(dto.getCartonCode());
        parcel.setContainerId(dto.getContainerId());
        parcel.setSourceNo(parcelDto.getSourceNo());

        parcel.setDeliverStartDate(LocalDateTimeUtil.parse(parcelDto.getDeliverStartDate(), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        parcel.setDeliverEndDate(LocalDateTimeUtil.parse(parcelDto.getDeliverEndDate(), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        parcel.setTargetWarehouseCode(parcelDto.getTargetWarehouseCode());

        parcel.setDeliveryUserId(parcelDto.getDeliveryUserId());
        parcel.setEnterpriseId(parcelDto.getEnterpriseId());

        parcel.setWeight(BigDecimal.ZERO);
        parcel.setVolume(BigDecimal.ZERO);
        for (ParcelDetailDto detailDto : parcelDto.getList()) {
            var weight = NumberUtil.toBigDecimal(detailDto.getWeight());
            parcel.setWeight(NumberUtil.add(parcel.getWeight(), weight));

            var volume = NumberUtil.toBigDecimal(detailDto.getVolume());
            parcel.setVolume(NumberUtil.add(parcel.getVolume(), volume));
        }

        parcel.setParcelDetail(JSONUtil.toJsonStr(parcelDto.getList()));

        var temperAreaConfig = temperAreaConfigService.getById(dto.getTemperId());

        // 生成SPU
        var spu = new Spu();
        spu.setId(id);
        spu.setSourceId(Constants.SOURCE_ID_DEFAULT + id);
        spu.setSpuCode(id);
        spu.setCategoryId("0"); // 包裹的商品分类默认设置0
        spu.setName(parcelDto.getParcelNo());
        spu.setSupplierCode(parcelDto.getSourceNo());
        spu.setIsPackingBox("1");
        spu.setBigProduct(0);
        spu.setStandard(1);

        spu.setImgUrl(parcel.getImgUrl());
        spu.setTemperatureZoneCode(temperAreaConfig.getTemperatureZoneCode());
        spu.setErrorMax(BigDecimal.ZERO);
        spu.setErrorMin(BigDecimal.ZERO);
        // 生成SKU
        Sku sku = new Sku();
        sku.setId(spu.getId());
        sku.setBarcodeId(dto.getCargoId());
        sku.setSourceId(spu.getSourceId());
        sku.setSpuId(spu.getId());
        sku.setSellerCode(parcelDto.getSourceNo());
        sku.setSiteCode("ctshop");
        sku.setProductSysCode(parcelDto.getParcelNo());
        sku.setBarcodeCode(parcelDto.getParcelNo());
        sku.setBarcodeSysCode(parcelDto.getParcelNo());
        sku.setBarcodePrice(BigDecimal.ZERO);
        sku.setSpecPrice(BigDecimal.ZERO);
        sku.setCostPrice(BigDecimal.ZERO);
        sku.setOutputTax(BigDecimal.ZERO);
        sku.setSpecification("0");
        sku.setVolume(parcel.getVolume());
        sku.setFloatRange(BigDecimal.ZERO);
        sku.setSkuUrl(spu.getImgUrl());
        sku.setSupplierCode(spu.getSupplierCode());

        ParcelDataDto dataDto = new ParcelDataDto();
        dataDto.setSpu(spu);
        dataDto.setSku(sku);
        dataDto.setParcel(parcel);

        Warehouse warehouse = warehouseService.getOne(Wrappers.<Warehouse>lambdaQuery().eq(Warehouse::getWarehouseCode, parcel.getReceiveRep()).last("limit 1"));
        if (warehouse != null) {
            sendMsg(dataDto, warehouse);

            // 初始化仓库采购单
            initWarehousePurchaseOrder(dataDto, warehouse);

            // 生成门禁
            tDeliveryOrderInfoService.access("", parcelDto.getParcelNo(), Constants.ACCESS_TYPE_FIVE, parcelDto.getReceiveRep());
        }

        Warehouse warehouse1 = warehouseService.getOne(Wrappers.<Warehouse>lambdaQuery().eq(Warehouse::getWarehouseCode, parcel.getTargetWarehouseCode()).last("limit 1"));
        if (warehouse1 != null) {
            sendMsg(dataDto, warehouse1);

            initWarehouseSaleOrder(dataDto, warehouse1);

            // 生成门禁
            tDeliveryOrderInfoService.access("", parcelDto.getParcelNo(), Constants.ACCESS_TYPE_SEVEN, parcelDto.getTargetWarehouseCode());
        }
    }

    public void initWarehousePurchaseOrder(ParcelDataDto dataDto, Warehouse warehouse) {
        Spu spu = dataDto.getSpu();
        Sku sku = dataDto.getSku();
        Parcel parcel = dataDto.getParcel();

        PurchaseOrder purchaseOrder = new PurchaseOrder();
        PurchaseOrderDetail purchaseOrderDetail = new PurchaseOrderDetail();
        GoodsBox goodsBox = new GoodsBox();

        purchaseOrder.setWarehouseCode(parcel.getReceiveRep());
        purchaseOrder.setSupplierCode(parcel.getSourceNo());
        purchaseOrder.setDeliveryCode(parcel.getParcelNo());
        purchaseOrder.setPurchaseOrderCode(parcel.getParcelNo());
        purchaseOrder.setServiceCode(parcel.getParcelNo());
        purchaseOrder.setServiceType(1);
        purchaseOrder.setSourceId(parcel.getParcelNo());
        purchaseOrder.setDeliveryWay("2");
        purchaseOrder.setPurchaseSource("0");
        purchaseOrder.setConfirmStatus("1");
        purchaseOrder.setDeliveryTime(LocalDateTime.now());
        purchaseOrder.setDeliveryStatus("0");
        purchaseOrder.setDistributionCost(BigDecimal.ZERO);
        purchaseOrder.setPrice(BigDecimal.ZERO);
        purchaseOrder.setPurchaseType(Constants.PURCHASE_TYPE_ZERO);
        purchaseOrder.setSourceOrigin(1);

        purchaseOrderDetail.setSpuId(spu.getId());

        purchaseOrderDetail.setSourceId(parcel.getParcelNo());
        purchaseOrderDetail.setPurchaseOrderCode(purchaseOrder.getPurchaseOrderCode());
        purchaseOrderDetail.setBoxCode(parcel.getCartonCode());
        purchaseOrderDetail.setBatchCode(purchaseOrder.getPurchaseOrderCode());
        purchaseOrderDetail.setOutStock(com.lvy.hczn.front.common.constant.Constants.OUT_STOCK_ZERO);
        purchaseOrderDetail.setSpecCode(parcel.getParcelNo());
        purchaseOrderDetail.setPrice(BigDecimal.ZERO);
        purchaseOrderDetail.setSkuCode(sku.getId());
        purchaseOrderDetail.setWeight(parcel.getWeight());
        purchaseOrderDetail.setPurchaseWeight(parcel.getWeight());
        purchaseOrderDetail.setQuantity(1);
        purchaseOrderDetail.setPurchaseQuantity(1);
        purchaseOrderDetail.setUnit("件");
        purchaseOrderDetail.setSupplierCode(parcel.getSourceNo());
        purchaseOrderDetail.setStatus("0");
        purchaseOrderDetail.setVolume(parcel.getVolume());
        purchaseOrderDetail.setProduceDate(LocalDateTime.now());
        purchaseOrderDetail.setWarrantyDate(7);
        purchaseOrderDetail.setDataType("BGRK");
        purchaseOrderDetail.setNumberOfPerBox(1);
        purchaseOrderDetail.setProducerId("0");
        purchaseOrderDetail.setMaterialProcessId("无");
        purchaseOrderDetail.setWeightOfPerBox(BigDecimal.ZERO);

        purchaseOrder.setList(CollUtil.newArrayList(purchaseOrderDetail));

        List<GoodsBox> boxCodeList = new ArrayList<>();

        goodsBox.setBoxCode(purchaseOrderDetail.getBoxCode());
        goodsBox.setGoodsBoxSpecId(parcel.getContainerId());
        boxCodeList.add(goodsBox);

        log.error("purchaseOrder:{}", JSON.toJSONString(purchaseOrder));

        DeliveryOrder deliveryOrder = new DeliveryOrder();
        List<WarehousingEntry> entryList = new ArrayList<>();

        tDeliveryOrderInfoService.generateDeliver(purchaseOrder, deliveryOrder, entryList);

        tDeliveryOrderInfoService.sendMsg(deliveryOrder, entryList, boxCodeList, warehouse, purchaseOrder);

    }


    public void initWarehouseSaleOrder(ParcelDataDto dataDto, Warehouse warehouse) {
        Spu spu = dataDto.getSpu();
        Sku sku = dataDto.getSku();
        Parcel parcel = dataDto.getParcel();

        SaleOrder saleOrder = new SaleOrder();

        saleOrder.setSaleOrderCode(parcel.getParcelNo());
        saleOrder.setMemberCode(parcel.getParcelNo());
        saleOrder.setDeliveryCode(parcel.getParcelNo());
        saleOrder.setDeliveryTime(parcel.getDeliverEndDate());
        saleOrder.setName(parcel.getParcelNo());
        saleOrder.setWarehouseCode(warehouse.getWarehouseCode());
        saleOrder.setRemark(parcel.getRemark());
        saleOrder.setServiceCode(parcel.getParcelNo());
        saleOrder.setReturnOfGoods(false);
        saleOrder.setGoodsRejected(false);
        saleOrder.setServiceCode(parcel.getParcelNo());
        saleOrder.setType("1");
        saleOrder.setSourceOrigin(0);
        saleOrder.setStatus("0");
        saleOrder.setSourceId(spu.getSourceId());
        saleOrder.setDeliveryClerk(parcel.getDeliveryUserId());


        SaleOrderDetail saleOrderDetail = new SaleOrderDetail();
        saleOrderDetail.setSaleOrderCode(saleOrder.getSaleOrderCode());
        saleOrderDetail.setSourceId(saleOrder.getSourceId());
        saleOrderDetail.setQuantity(1);
        saleOrderDetail.setGoodsCode(spu.getName());
        saleOrderDetail.setSkuCode(sku.getId());
        saleOrderDetail.setSupplierCode(spu.getSupplierCode());
        saleOrderDetail.setSupplierName(spu.getSupplierCode());
        saleOrderDetail.setRemark(parcel.getRemark());
        saleOrderDetail.setOutStock(com.lvy.hczn.front.common.constant.Constants.OUT_STOCK_ZERO);
        saleOrderDetail.setSpecCode(parcel.getParcelNo());
        saleOrderDetail.setSpuId(spu.getId());
        saleOrderDetail.setQuantity(1);
        saleOrderDetail.setUnit("无");
        saleOrderDetail.setWeight(parcel.getWeight());
        saleOrderDetail.setVolume(parcel.getVolume());
        saleOrderDetail.setTakeDeliveryOf(0);
        saleOrderDetail.setStatus("0");
        saleOrderDetail.setDataType("BGCK");

        saleOrder.setList(CollUtil.newArrayList(saleOrderDetail));

        ParamInfo<SaleOrder> info = new ParamInfo<>();
        info.setData(saleOrder);
        String topic = warehouseService.selectRegionAreaTopic(warehouse);
        String tag = warehouse.getWarehouseCode() + "_" + MqConstants.TOPIC_WAREHOUSE_DELIVERY_SALE;
        try {
            producerUtil.sendAsyncMsg(topic, tag, JSON.toJSONString(info).getBytes(StandardCharsets.UTF_8), IdUtil.fastSimpleUUID());
        } catch (Exception e) {
            throw new UtilException("数据发送异常");
        }
    }


    private void sendMsg(ParcelDataDto dataDto, Warehouse warehouse) {
        String topic = warehouseService.selectRegionAreaTopic(warehouse);

        ParamInfo<ParcelDataDto> paramInfo2 = new ParamInfo<>();
        paramInfo2.setData(dataDto);
        String tagParcel = warehouse.getWarehouseCode() + "_" + MqConstants.TOPIC_SYNC_PARCEL;

        log.error("包裹信息:{}", JSON.toJSONString(paramInfo2));
        try {
            producerUtil.sendMsg(topic, tagParcel, JSONUtil.toJsonStr(paramInfo2).getBytes(StandardCharsets.UTF_8), IdUtil.fastSimpleUUID());
        } catch (Exception e) {
            log.error("包裹信息发送异常:{}", e);
            throw new UtilException("信息发送异常");
        }
    }
}
